﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Universum.Model.Domain.MyClasses;
using Universum.Infrastructure.Persistence;
using Universum.Infrastructure.Persistence.Queries.MyClasses;
using Universum.Model.Services.Classes;
using System.IO;
using System.Security.Principal;
using Universum.Model.Domain.Classes;

namespace Universum.Model.Services.MyClasses
{
	public class SubmissionServiceImpl : ISubmissionService
	{
		public const string SUBMISSION_PATH = @"LabWorkSubmissions";
		IRepository _Repository;
		IFileService _FileService;
		
		IPrincipal _Principal;
		public SubmissionServiceImpl(IRepository repository,
			IFileService fileService,
			
			IPrincipal principal)
		{
			_Repository = repository;
			_FileService = fileService;
			_Principal = principal;
			
		}
		#region ISubmissionService Members

		public Universum.Model.Domain.MyClasses.LabWorkSubmission CreateNewSubmissionOrGetBy(Guid guid, string username)
		{
			
			var found = _Repository.Query(new SubmissionByLabWorkArticleIdAndUsername(guid, username)).FirstOrDefault();
			if (found != null) return found;
			return new LabWorkSubmission
			{
				ID = Guid.NewGuid(),
				LabWorkArticleId = guid,
				Username = username
			};
		}

		#endregion

		#region ISubmissionService Members


		public void Register(LabWorkSubmission submission, HttpPostedFileBase work)
		{
			if (work != null)
			{
				var update = _Repository.Load<LabWorkSubmission>(submission.ID);
				update.Username = _Principal.Identity.Name;
				update.FileName = work.FileName;
				update.ContentType = work.ContentType;

				string pathToLab = get_path_to_lab(update);

				_FileService.WriteToDiskFrom(work, pathToLab);
				update.SubmittedAt = DateTime.Now;
				_Repository.SaveOrUpdate(update);
			}
		}

		private string get_path_to_lab(LabWorkSubmission submission)
		{
			string pathToLab =
						 Path.Combine(
						 Path.Combine(
						 Path.Combine(SUBMISSION_PATH,
						 submission.LabWorkArticleId.ToString())
						 ,  submission.Username),
						 submission.FileName);
			return pathToLab;
		}

		#endregion

		#region ISubmissionService Members


		public void RemoveByLabWorkId(Guid labWorkId)
		{
			var submissions = _Repository.Query(
						new SubmissionByLabWorkArticleId(labWorkId));
			foreach (var submission in submissions)
			{
				_Repository.Remove(submission);
			}
		}

		#endregion

		#region ISubmissionService Members


		public LabWorkSubmission GetSubmisionById(Guid id)
		{
			return _Repository.Load<LabWorkSubmission>(id);
		}

		public Stream GetFileSubmisionStream(LabWorkSubmission submision)
		{
			return _FileService.GetStreamFor(get_path_to_lab(submision));
		}

		#endregion

		#region ISubmissionService Members


		public IList<LabWorkSubmission> GetSubmisionsByLabWorkId(Guid guid)
		{
			return _Repository.Query(new Infrastructure.Persistence.Queries.MyClasses.SubmissionByLabWorkArticleId(guid)).ToList() ;
		}

		#endregion
	}
}
